<template>
  <div class="video-time-line-container">
    <div class="video-time-line-inner-box" v-if="canPlayBack">
      <el-form class="video-form" :model="videoForm" :rules="rules" ref="timeForm" :inline="true">
        <el-form-item v-show="isPlayBackUrl && isHuiYan">
          <el-select @change="handleVideoScaleChange" style="width: 100%;" v-model="videoBackControlParams.scale" placeholder="请选择倍速">
            <el-option
              v-for="index in 4"
              :key="index"
              :label="Math.pow(2, index - 1) + 'x'"
              :value="Math.pow(2, index - 1)">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item prop="date">
          <el-date-picker
            v-model="videoForm.date"
            align="right"
            type="date"
            placeholder="请选择日期">
          </el-date-picker>
        </el-form-item>
        <el-form-item prop="timeRange">
          <el-time-picker
            is-range
            v-model="videoForm.timeRange"
            :picker-options="pickerOptions"
            range-separator="至"
            start-placeholder="开始时间"
            end-placeholder="结束时间"
            placeholder="选择时间范围">
          </el-time-picker>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleUpdateBackTime">确定</el-button>
        </el-form-item>
        <el-form-item>
          <el-button class="clear-btn" type="success" @click="reset">重置</el-button>
        </el-form-item>
      </el-form>
      <slot />
      <VideoTimelineSlider
        v-if="showTimelineSlider"
        class="video-progress-bar"
        :value="videoCurrentTime"
        :min="timeSegment.beginTime"
        :max="timeSegment.endTime"
        @seedVideo="handleSeedVideo"></VideoTimelineSlider>
      <div class="video-time-line-box">
        <TimeLine
          ref="Timeline"
          :enableZoom="false"
          :enableDrag="false"
          :showDateAtZero="false"
          :showCenterLine="false"
          class="video-time-line"
          :initZoomIndex="11"
          :initTime="initTime"
          :lineHeightRatio="{hover: 0.55,date: 0.4}"
          :customShowTime="customShowTime"
          :extendZOOM="extendZOOM"
          :formatTime="formatTime"
          :timeSegments="timeSegments"
          :hoverTimeFormat="hoverTimeFormat"
          @click_timeline="handleTimeLineClick"
          @click_timeSegments="handleTimeSegmentsClick"
        ></TimeLine>
      </div>
    </div>
    <div class="video-player-box" v-else>
      <slot />
    </div>
  </div>
</template>

<script>
import Vue from 'vue'
// import VideoTimeline from '@wanglin1994/video-timeline'
import VideoTimelineSlider from '@/components/video-timeline-slider'
// import { getVideoBackControl, getVideoBackUrl } from '@/api/subSystem/basicInfo'
// Vue.use(VideoTimeline)
export default {
  name: 'video-timeline',
  components: {
    VideoTimelineSlider
  },
  props: {
    isPlaying: {
      type: Boolean,
      default: false
    },
    canPlayBack: {
      type: Boolean,
      default: false
    },
    videoCurrentTime: {
      type: Number,
      default: 0
    },
    videoData: {
      type: Object,
      default() {
        return {}
      }
    },
    isHuiYan: {
      type: Boolean,
      default: false
    }
  },
  data() {
    const $dayjs = this.$dayjs
    return {
      scaleTimer: null,
      data: {
        backUrl: '',
        backControlUrl: ''
      },
      pickerOptions: {
      },
      videoForm: {
        date: '',
        timeRange: [
          new Date(this.$dayjs().startOf('day').format()), new Date(this.$dayjs().endOf('day').format())
        ]
      },
      rules: {
        date: {
          type: 'date', required: true, message: ''
        },
        timeRange: {
          required: true, message: '', type: 'array'
        }
      },
      videoBackControlParams: {
        scale: 1,
        range: 0
      },
      initTime: $dayjs().format('YYYY-MM-DD 12:00:00').valueOf(),
      extendZOOM: [
        {
          zoom: 25,
          zoomHourGrid: 0.5
        }
      ],
      timeSegments: [
        {
          name: '时间段1',
          color: '#006eff',
          startRatio: 0.65,
          endRatio: 0.9
        }
      ]
    }
  },
  computed: {
    timeSegment() {
      const timeSegment = this.timeSegments[0]
      const beginTimeStr = timeSegment.beginTime ? this.$dayjs(timeSegment.beginTime).format('YYYY-MM-DD HH:mm:ss') : ''
      const endTimeStr = timeSegment.endTime ? this.$dayjs(timeSegment.endTime).format('YYYY-MM-DD HH:mm:ss') : ''
      timeSegment.beginTimeStr = beginTimeStr
      timeSegment.endTimeStr = endTimeStr
      return timeSegment
    },
    isTimeSegmentComplete() {
      return this.timeSegment.beginTimeStr && this.timeSegment.endTimeStr
    },
    isPlayBackUrl() {
      return this.data.backUrl
    },
    isScalePlay() {
      return parseInt(this.videoBackControlParams.scale) > 1
    },
    showTimelineSlider() {
      return this.isPlayBackUrl && !this.isScalePlay && this.isPlaying && !this.videoData.isScalePlay
    }
  },
  mounted() {
    this.data = {
      ...this.data,
      ...this.videoData
    }
  },
  beforeDestroy() {
    this.clearScaleTime()
  },
  methods: {
    handleUpdateBackTime() {
      this.$refs.timeForm.validate((valid) => {
        if (valid) {
          const date = this.$dayjs(this.videoForm.date).format('YYYY-MM-DD')
          const timeRange = this.videoForm.timeRange.map(item => {
            const dateStr = `${date} ${this.$dayjs(item).format('HH:mm:ss')}`
            return this.$dayjs(dateStr).valueOf()
          })
          this.resetVideoSeed()
          this.updateTimeSegment(timeRange[0], timeRange[1], date)
        }
      })
    },
    handleVideoScaleChange(val) {
      this.getVideoBackControl({
        scale: val,
        command: 'scale'
      })
      this.$emit('scalePlay')
      if (val > 1) {
        this.calcScaleTime(val)
      } else {
        this.clearScaleTime()
      }
    },
    clearScaleTime() {
      if (this.scaleTimer) {
        clearInterval(this.scaleTimer)
      }
    },
    calcScaleTime(val) {
      this.clearScaleTime()
      this.scaleTimer = setInterval(() => {
        this.$emit('scalePlusTime')
      }, 1000 / (val * 1.2))
    },
    resetScale() {
      this.clearScaleTime()
      this.videoBackControlParams = {
        scale: 1,
        range: 0
      }
    },
    async getBackPlayUrl() {
      this.$emit('updateUrlBefore')
      const data = this.data
      this.resetScale()
      const backUrlRes = await getVideoBackUrl({
        starttime: this.timeSegment.beginTimeStr,
        endtime: this.timeSegment.endTimeStr,
        machineNum: data.machineNum,
        id: data.id
      })

      if (backUrlRes.code === 200) {
        this.data.backUrl = backUrlRes.data.playUrl
        this.data.backControlUrl = backUrlRes.data.backControlUrl

        this.$emit('updateVideoUrl', backUrlRes.data.playUrl)
        this.$emit('isPlayBackUrl', this.isPlayBackUrl)
      }
    },
    async getVideoBackControl(params = this.videoBackControlParams) {
      const para = {
        backControlUrl: this.data.backControlUrl,
        id: this.data.id,
        ...params
      }
      const controlRes = await getVideoBackControl(para)

      if (controlRes.code === 200) {
        this.$message.success('操作成功')
      } else {
        this.$emit('seedError')
      }
      return controlRes
    },
    reset() {
      this.formReset()
      this.clearTimeSegments()
      this.clearScaleTime()
      this.data.backUrl = ''
      this.data.backControlUrl = ''
      this.$emit('updateVideoUrl')
      this.$emit('isPlayBackUrl', this.isPlayBackUrl)
    },
    formReset() {
      this.$refs.timeForm.resetFields()
      this.videoBackControlParams = {
        scale: 1,
        range: 0
      }
    },
    clearTimeSegments() {
      const newTimeSegment = {
        ...this.timeSegments[0]
      }
      newTimeSegment.beginTime = undefined
      newTimeSegment.endTime = undefined
      this.timeSegments = [newTimeSegment]
    },
    updateTimeSegment(beginTime, endTime, date) {
      this.timeSegments[0].beginTime = beginTime
      this.timeSegments[0].endTime = endTime
      this.timeSegments = [...this.timeSegments]
      this.initTime = this.$dayjs().format(`${date} 12:00:00`).valueOf()
      this.resetPlayScale()
      this.getBackPlayUrl()
    },
    resetPlayScale() {
      this.videoBackControlParams.scale = 1
    },
    hoverTimeFormat(time) {
      // 小于今天，大于今天的时间不显示
      if (
        this.$dayjs(time).isBefore(this.$dayjs().format('YYYY-MM-DD 00:00:00')) ||
        this.$dayjs(time).isAfter(this.$dayjs().format('YYYY-MM-DD 23:59:59'))
      ) {
        return ''
      }
      return this.$dayjs(time).format('HH:mm:ss')
    },
    formatTime(time) {
      // 下一天的00:00显示24:00
      if (time.valueOf() - this.$dayjs(this.initTime).valueOf() === 1000 * 3600 * 12) {
        return '24:00'
      }
      if (
        time.hour() === 0 &&
        time.minute() === 0 &&
        time.millisecond() === 0
      ) {
        return time.format('HH:mm')
      }
    },
    customShowTime(date, zoomIndex) {
      // 当zoomIndex等于11，也就是等于我们开展的zoom时才自己处理
      if (zoomIndex === 11) {
        // 时间是2的倍数时才会显示
        return date.getHours() % 2 === 0 && date.getMinutes() === 0
      }
    },
    handleTimeSegmentsClick(segment, currentFormatterTime, currentUnixTime) {
      this.seedVideo(parseInt((currentUnixTime - segment[0].beginTime) / 1000))
    },
    seedVideo(range) {
      return this.getVideoBackControl({
        range,
        command: 'play'
      }).then(res => {
        if (res.code === 200) {
          this.$emit('seedVideo', range)
        }
      })
    },
    resetVideoSeed() {
      this.$emit('seedVideo', 0)
    },
    handleSeedVideo(range) {
      if (this.isHuiYan) {
        this.seedVideo(range)
      } else {
        const val = range * 1000 + this.timeSegment.beginTime
        this.handleTimeLineClick(val)
      }
    },
    handleTimeLineClick(val) {
      const value = parseInt(val)
      const valueFormat = new Date(this.$dayjs(value).format())
      const newSegments = {}
      if (!this.timeSegment.beginTime) {
        newSegments.beginTime = value
        this.timeSegment.beginTime = value
        this.videoForm.timeRange[0] = valueFormat
        this.videoForm.timeRange = [...this.videoForm.timeRange]
        return
      }
      if (this.timeSegment.endTime) {
        if (value < this.timeSegment.beginTime) {
          newSegments.beginTime = value
          this.videoForm.timeRange[0] = valueFormat
          this.videoForm.timeRange = [...this.videoForm.timeRange]
        }
        if (this.timeSegment.beginTime < value < this.timeSegment.endTime) {
          newSegments.beginTime = value
          this.videoForm.timeRange[0] = valueFormat
          this.videoForm.timeRange = [...this.videoForm.timeRange]
        }
        if (value > this.timeSegment.endTime) {
          newSegments.endTime = value
          this.videoForm.timeRange[1] = valueFormat
          this.videoForm.timeRange = [...this.videoForm.timeRange]
        }
      } else {
        if (value < this.timeSegment.beginTime) {
          const newEndTime = this.timeSegment.beginTime
          newSegments.beginTime = value
          newSegments.endTime = newEndTime
          this.videoForm.timeRange[1] = valueFormat
          this.videoForm.timeRange = this.videoForm.timeRange.reverse()
          this.videoForm.timeRange = [...this.videoForm.timeRange]
        } else {
          newSegments.endTime = value
          this.timeSegment.endTime = value
          this.videoForm.timeRange[1] = valueFormat
          this.videoForm.timeRange = [...this.videoForm.timeRange]
        }
      }
      this.timeSegments = [{
        ...this.timeSegment,
        ...newSegments
      }]
      if (this.isTimeSegmentComplete) {
        this.getBackPlayUrl()
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.video-time-line-container{
  width: 100%;
  height: 100%;
  .video-time-line-inner-box{
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    .video-form{
      display: flex;
      margin-bottom: 5px;
      ::v-deep .el-form-item{
        margin-bottom: 0;
      }
    }
    .video-progress-bar{
      position: absolute;
      left: 20px;
      right: 20px;
      bottom: 40px;
    }
    .video-time-line-box {
      height: 80px;
      flex-shrink: 0;
      .video-time-line{
        height: 100%;
      }
    }
  }
  .video-player-box{
    width: 100%;
    height: 100%;
  }
}

::v-deep .el-range-separator{
  width: 20px;
}
</style>
